/* Copyright  2009
   @Author
   Richard Changde Yin            e-mail yinchangde@hotmail.com

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/**
 * @filename: mem_field.h
 */
#ifndef __MEM_FIELD_H__
#define __MEM_FIELD_H__

#include <os.h>
#include <common.h>
#include <error.h>

//used by FieldNameList

/* m_ctype.h*/
typedef struct charset_info_st CHARSET_INFO;

class m_field_def
{
    m_field_def& operator = (const m_field_def& def);

public:
    m_field_def()
    {
      init();
    }

    virtual ~m_field_def(){}

    void init() {
      bzero(fldName_,IDENTIFIER_LENGTH);
      type_      = COLLAPSAR_TYPE_UNKNOWN;
      length_    = 0;
      offset_    = 0;
      bindVal_   = NULL;
      isDefault_ = false;
      isNull_    = false;
      isPrimary_ = false;
      isUnique_  = false;
      fldNameRealLen    = 0    ;
      charset    = &my_charset_bin;
   }

    char fldName_[IDENTIFIER_LENGTH];

    enum_field_types   type_;

    size_t           length_;
    size_t           offset_;
    //currently default value is supported for string and binary
    //less than length 32 bytes
    //char defaultValueBuf_[DEFAULT_VALUE_BUF_LENGTH];
    const     CHARSET_INFO *    charset      ;
    //used only in case of binding fields
    void *bindVal_;

    bool isNull_;
    bool isPrimary_;
    bool isDefault_;
    bool isUnique_;

    uint8_t  null_bit;                    /* If column may be 0 */
    uint16_t null_pos;                    /* position for null marker */

    uint32_t fldNameRealLen ;
    //TODO::width and scale
};

class M_FieldNode
{
    M_FieldNode& operator = (M_FieldNode&);
public:
    M_FieldNode():fldDef(0),next(0){}

    M_FieldNode(m_field_def * _flddef):fldDef(_flddef),next(0)
    {
    }
    virtual ~M_FieldNode()
    {
      delete fldDef;
      fldDef = 0 ;
    }
    m_field_def *fldDef;
    M_FieldNode *next  ;
};


class M_FieldIterator
{
	M_FieldNode *iter;
public:
    M_FieldIterator(M_FieldNode *ptr) { iter = ptr; }
    bool hasElement()
    {
      if (iter == NULL) return false;
      else return true;
    }
    m_field_def* nextElement()
    {
        if (iter == NULL) { return NULL;}
        M_FieldNode *node = iter;
        iter = iter ->next;
        return (node->fldDef);
    }
};

typedef struct field_info_t
{
    field_info_t(){}
    char fldName[IDENTIFIER_LENGTH];
    enum_field_types type ;
    size_t length ;
    size_t offset ;
    char defaultValueBuf[DEFAULT_VALUE_BUF_LENGTH];
    bool isNull   ;
    bool isPrimary;
    bool isDefault;
    bool isUnique;
} M_FIELD_INFO ;


//Internal class used to implement the field list information
//to create the table
class M_FieldList
{
   uint32_t _size ;
   M_FieldList& operator = (M_FieldList&);
   M_FieldList(M_FieldList&);
public:

    M_FieldNode *head;

    M_FieldList():_size(0),head(0){}

    BackEnd::DbRetVal append(m_field_def* fDef);

    BackEnd::DbRetVal remove(const char* fldName);

    BackEnd::DbRetVal removeAll();

    BackEnd::DbRetVal updateBindVal(const char *fldName, void *val);

    void * getBindField     (const char *fldName);

    int16_t getFieldOffset (const char *fldName);

    int16_t getFieldOffset (int fldpos);

    //Returns position of field in the list:count starting from 1
    int16_t getFieldPosition(const char *fldName);

    enum_field_types getFieldType(const char *fldName);

    size_t getFieldLength(const char *fldName);

    BackEnd::DbRetVal getFieldInfo(const char *fldName, m_field_def *&info);

    uint32_t getTupleSize();

    M_FieldIterator getIterator()
    {
        M_FieldIterator iter(head);
        return iter;
    }

    inline uint32_t size() { return _size; }

};
#endif //__MEM_FIELD_H__
